<!DOCTYPE html>
<!--
Copyright (c) 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/base/task.html">
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/extras/importer/trace_event_importer.html">
<link rel="import" href="/tracing/model/event_set.html">
<link rel="import" href="/tracing/ui/timeline_track_view.html">

<script>
'use strict';

tr.b.unittest.testSuite(function() {
  const EventSet = tr.model.EventSet;
  const SelectionState = tr.model.SelectionState;
  const Task = tr.b.Task;

  test('instantiate', function() {
    const numThreads = 500;
    const model = tr.c.TestUtils.newModelWithEvents([], {
      shiftWorldToZero: false,
      pruneContainers: false,
      customizeModelCallback(model) {
        const p100 = model.getOrCreateProcess(100);
        for (let i = 0; i < numThreads; i++) {
          const t = p100.getOrCreateThread(101 + i);
          if (i % 2 === 0) {
            t.sliceGroup.beginSlice('cat', 'a', 100);
            t.sliceGroup.endSlice(110);
          } else {
            t.sliceGroup.beginSlice('cat', 'b', 50);
            t.sliceGroup.endSlice(120);
          }
        }
      }
    });

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;
    timeline.style.maxHeight = '600px';
    this.addHTMLOutput(timeline);
  });

  test('addAllEventsMatchingFilterToSelectionAsTask', function() {
    const model = new tr.Model();
    const p1 = model.getOrCreateProcess(1);
    const t1 = p1.getOrCreateThread(1);

    t1.sliceGroup.pushSlice(
        new tr.model.ThreadSlice('', 'a', 0, 1, {}, 3));
    t1.sliceGroup.pushSlice(
        new tr.model.ThreadSlice('', 'b', 0, 1.1, {}, 2.8));

    const t1asg = t1.asyncSliceGroup;
    t1asg.slices.push(
        tr.c.TestUtils.newAsyncSliceNamed('a', 0, 1, t1, t1));
    t1asg.slices.push(
        tr.c.TestUtils.newAsyncSliceNamed('b', 1, 2, t1, t1));

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;

    let expected = new tr.model.EventSet(
        [t1asg.slices[0], t1.sliceGroup.slices[0]]);
    let result = new tr.model.EventSet;
    let filterTask = timeline.addAllEventsMatchingFilterToSelectionAsTask(
        new tr.c.TitleOrCategoryFilter('a'), result);
    Task.RunSynchronously(filterTask);
    assert.isTrue(result.equals(expected));

    expected = new tr.model.EventSet(
        [t1asg.slices[1], t1.sliceGroup.slices[1]]);
    result = new tr.model.EventSet();
    filterTask = timeline.addAllEventsMatchingFilterToSelectionAsTask(
        new tr.c.TitleOrCategoryFilter('b'), result);
    Task.RunSynchronously(filterTask);
    assert.isTrue(result.equals(expected));
  });

  test('emptyThreadsDeleted', function() {
    const model = new tr.Model();
    const p1 = model.getOrCreateProcess(1);
    const t1 = p1.getOrCreateThread(1);

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;

    assert.isFalse(timeline.hasVisibleContent);
  });

  test('filteredCounters', function() {
    const model = new tr.Model();
    const c1 = model.kernel.getOrCreateCpu(0);
    c1.getOrCreateCounter('', 'b');

    const p1 = model.getOrCreateProcess(1);
    const ctr = p1.getOrCreateCounter('', 'a');
    const series = new tr.model.CounterSeries('a', 0);
    series.addCounterSample(0, 1);
    ctr.addSeries(series);

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;

    assert.isTrue(timeline.hasVisibleContent);
  });

  test('filteredCpus', function() {
    const model = new tr.Model();
    const c1 = model.kernel.getOrCreateCpu(1);
    c1.getOrCreateCounter('', 'a');

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;

    assert.isTrue(timeline.hasVisibleContent);
  });

  test('filteredProcesses', function() {
    const model = new tr.Model();
    const p1 = model.getOrCreateProcess(1);
    p1.getOrCreateCounter('', 'a');

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;

    assert.isTrue(timeline.hasVisibleContent);
  });

  test('filteredThreads', function() {
    const model = new tr.Model();
    const p1 = model.getOrCreateProcess(1);
    const t1 = p1.getOrCreateThread(2);
    t1.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({start: 0, duration: 1}));

    const timeline = document.createElement('tr-ui-timeline-track-view');
    timeline.model = model;

    assert.isTrue(timeline.hasVisibleContent);
  });

  test('interestRange', function() {
    const events = [
      {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'c', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'c', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'a', args: {}, pid: 52, ts: 634, cat: 'foo', tid: 53, ph: 'E'}
    ];
    const model = tr.c.TestUtils.newModelWithEvents([events]);
    const trackView = document.createElement('tr-ui-timeline-track-view');
    trackView.model = model;
    this.addHTMLOutput(trackView);

    const slice = model.processes[52].threads[53].sliceGroup.slices[2];
    trackView.viewport.interestRange.setMinAndMax(slice.start, slice.end);
  });

  test('emptyInterestRange', function() {
    const events = [
      {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'c', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'c', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'a', args: {}, pid: 52, ts: 634, cat: 'foo', tid: 53, ph: 'E'}
    ];
    const model = tr.c.TestUtils.newModelWithEvents([events]);
    const trackView = document.createElement('tr-ui-timeline-track-view');
    trackView.model = model;
    this.addHTMLOutput(trackView);
    trackView.viewport.interestRange.reset();
  });


  test('thinnestInterestRange', function() {
    const events = [
      {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'c', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'c', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'a', args: {}, pid: 52, ts: 634, cat: 'foo', tid: 53, ph: 'E'}
    ];
    const model = tr.c.TestUtils.newModelWithEvents([events]);
    const trackView = document.createElement('tr-ui-timeline-track-view');
    trackView.model = model;
    this.addHTMLOutput(trackView);
    trackView.viewport.interestRange.reset();

    const slice = model.processes[52].threads[53].sliceGroup.slices[2];
    trackView.viewport.interestRange.setMinAndMax(slice.start, slice.start);
  });
});
</script>
